package uk.co.hs.web.interceptor;

import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import uk.co.hs.service.admin.interfaces.WebUserServiceInterface;
import uk.co.hs.web.security.authentication.UtilisoftAuthentication;
import uk.co.hs.web.util.SessionTabsAccessibility;

/**
 * Intercepts a handler to put a tabs accessibility attribute into the session.
 */
public class TabsAccessibilityInterceptor implements HandlerInterceptor
{
  public static final String TABS_ACCESSIBILITY = "tabsAccessibility";

  /** ALWAYS ALLOWED PAGES. */
  public static final String ACCESS_DENIED_URL = "accessDenied.htm";
  public static final String ACCOUNT_LOCKED_URL = "accountLocked.htm";
  public static final String EXPIRED_PASSWORD_URL = "expiredPassword.htm";
  public static final String LOGIN_URL = "login.htm";
  public static final String FORWARDING_URL = "forwarding.htm";

  /** DASHBOARD **/
  public static final String DASHBOARD_URL = "dashboard.htm";

  /** SEARCH **/
  public static final String TABBED_SEARCH_URL = "tabbedSearch.htm";

  /** Messages */
  public static final String MESSAGE_LIST_URL = "messageList.htm";

  /** ADMIN */
  public static final String ROLE_EDIT_URL = "roleEdit.htm";
  public static final String ROLE_LIST_URL = "roleList.htm";
  public static final String USER_EDIT_URL = "userEdit.htm";
  public static final String USER_LIST_URL = "userList.htm";
  public static final String CHANGE_PASSWORD_URL = "changePassword.htm";
  public static final String SYSTEM_PARAMETER_LIST_URL = "systemParameterList.htm";
  public static final String SYSTEM_PARAMETER_EDIT_URL = "systemParameterEdit.htm";

  @Autowired(required = true)
  @Qualifier("hs_webUserService")
  private WebUserServiceInterface mUserService;

  //@Resource
  //private SystemParameterServiceInterface mSystemParameterService;

  /**
   * @see org.springframework.web.servlet.HandlerInterceptor
   * #preHandle(javax.servlet.http.HttpServletRequest,
   *            javax.servlet.http.HttpServletResponse,
   *            java.lang.Object)
   * {@inheritDoc}
   */
  public boolean preHandle(HttpServletRequest aRequest,
                           HttpServletResponse aResponse,
                           Object aHandler) throws Exception
  {
  	SecurityContext securityContext = SecurityContextHolder.getContext();
    if (securityContext != null)
    {
      Authentication authentication = securityContext.getAuthentication();
      if (authentication != null)
      {
        String userName = SecurityContextHolder.getContext().getAuthentication().getName();
        if (userName != null)
        {
        	Map<String, Boolean> allowedURLs = null;
        	if (SecurityContextHolder.getContext().getAuthentication() instanceof UtilisoftAuthentication)
        	{
        		UtilisoftAuthentication utilisoftAuth = (UtilisoftAuthentication) SecurityContextHolder.getContext().getAuthentication();
        		allowedURLs = utilisoftAuth.getAllowedURLS();
        	}

        	// Allowed URLs
        	if (allowedURLs == null)
        	{
        		allowedURLs = mUserService.getAllowedUrls(userName);
        	}

          SessionTabsAccessibility sessionTabsAccessibility = new SessionTabsAccessibility();
          Set<String> allowedUrlNames = allowedURLs.keySet();

          // Dashboard
          if (allowedUrlNames.contains(DASHBOARD_URL))
            sessionTabsAccessibility.setDashboardAccess(Boolean.TRUE);

          // Administration
          populateAdministrationPermissions(allowedUrlNames, sessionTabsAccessibility);

          // Search
          if (allowedUrlNames.contains(TABBED_SEARCH_URL))
            sessionTabsAccessibility.setTabbedSearchAccess(Boolean.TRUE);
         
          aRequest.getSession().setAttribute(TABS_ACCESSIBILITY, sessionTabsAccessibility);
        }
      }
    }
    return true;
  }

  /**
   * @see org.springframework.web.servlet.HandlerInterceptor
   * #postHandle(javax.servlet.http.HttpServletRequest,
   *             javax.servlet.http.HttpServletResponse,
   *             java.lang.Object,
   *             org.springframework.web.servlet.ModelAndView)
   * {@inheritDoc}
   */
  public void postHandle(HttpServletRequest aRequest,
                         HttpServletResponse aResponse,
                         Object aHandler,
                         ModelAndView aModelAndView) throws Exception
  { }

  /**
   * @see org.springframework.web.servlet.HandlerInterceptor
   * #afterCompletion(javax.servlet.http.HttpServletRequest,
   *                  javax.servlet.http.HttpServletResponse,
   *                  java.lang.Object, java.lang.Exception)
   * {@inheritDoc}
   */
  public void afterCompletion(HttpServletRequest aRequest,
                              HttpServletResponse aResponse,
                              Object aHandler,
                              Exception aException) throws Exception
  { }

  private void populateAdministrationPermissions(Set<String> aAllowedUrls,
                                                 SessionTabsAccessibility aSessionTabsAccessibility)
  {
    if (aAllowedUrls.contains(USER_LIST_URL))
      aSessionTabsAccessibility.setUserListAccess(Boolean.TRUE);
    if (aAllowedUrls.contains(USER_EDIT_URL))
      aSessionTabsAccessibility.setUserEditAccess(Boolean.TRUE);
    if (aAllowedUrls.contains(ROLE_LIST_URL))
      aSessionTabsAccessibility.setRoleListAccess(Boolean.TRUE);
    if (aAllowedUrls.contains(ROLE_EDIT_URL))
      aSessionTabsAccessibility.setRoleEditAccess(Boolean.TRUE);
    if (aAllowedUrls.contains(SYSTEM_PARAMETER_LIST_URL))
      aSessionTabsAccessibility.setSystemParameterListAccess(Boolean.TRUE);
    if (aAllowedUrls.contains(SYSTEM_PARAMETER_EDIT_URL))
      aSessionTabsAccessibility.setSystemParameterEditAccess(Boolean.TRUE);
    if (aAllowedUrls.contains(CHANGE_PASSWORD_URL))
      aSessionTabsAccessibility.setChangePasswordAccess(Boolean.TRUE);
    
    // Administration group accessibiliy permissions
    if (aAllowedUrls.contains(USER_LIST_URL)
        || aAllowedUrls.contains(ROLE_LIST_URL)
        || aAllowedUrls.contains(SYSTEM_PARAMETER_LIST_URL)
        || aAllowedUrls.contains(CHANGE_PASSWORD_URL))
    {
      aSessionTabsAccessibility.setAdministrationGroupAccess(Boolean.TRUE);
    }
  }

}
